import pandas as pd # database tool

# Read the csv file into the dataframe. Note that the file must contain headers and the headers
#     must match their usage in this code.
def load_database(level):
    df = pd.read_csv("./ARRL All Question Database.csv",header=0)
    match level:
        case 1:
            print("Case 1")
            df = df.loc[df['License Class'] == 'G']
        case 2:
            print("Case 2")
            df = df.loc[df['License Class'] == 'T']
        case 3:
            print("Case 3")
            df = df.loc[df['License Class'] == 'E']
    # do any manipulation here
    df.fillna(0,inplace=True)
    return df

# A short segment of code that pulls the random list with length <= nquestions on the topic
def choose_quiz_questions(df,topic,nquestions):
    possibleq = df.loc[df.iloc[:,topic-1]==1]
    Q = possibleq.sample(n=nquestions)
    return Q

# Prologue and collect data
#    Prologue motivates the quiz format.
#    Topics match the professor's recommendations 
#    The number of questions are flexible, and allows it to be short enough to keep
#        a student's attention.
#    TODO Improvement: request class of license as an additional filter
def start_screen():
    import sys # allows premature exit
    print("Welcome to the WPI Ham Radio Question Databank\n",
        "The standard licensing exams are 35 questions long. The\n", 
        "exam is taken in the timespan of one hour in front of a licensed proctor.\n\n",
        "This quiz uses multiple-choice test questions from the 2022-2027 question databank.\n",
        "You choose the number and topic of the questions. Some questions may bridge\n",
        "multiple topics.\n")
    print("\nChoose an exam level, 1. General, 2. Technician, 3. Extra, 4. All levels")
    level = None
    while level == None:
        level = input("Enter a number for the level. ")
        if level.upper() == "X":
            sys.exit()
        elif len(level) > 1 or level < "1" or level > "4":
            level = None
    level = int(level)
    # topics match column headings in database. This would be better handled with a dictionary 
    #     that precisely matches the column headings. For the rest of the code, we handle these by index number.
    print("\n1. Communications\t2. Electrical Engineering\t3. Atmospheric Science\n",
          "4. Space Science\t5. Robotic Engineering\t\t6.Physics\t7. Mathematics\n",
          "8. Computer Science\t9. Fun-to-try\n X. to exit")
    topic = None
    while topic == None:
        topic = input("Enter a number for the topic. ")
        if topic.upper() == "X":
            sys.exit()
        elif len(topic) > 1 or topic < "1" or topic > "9":
            topic = None
    topic = int(topic)
    squestions = None
    while squestions == None:
        squestions = input("Enter the maximum number of quiz questions you want to take: ")
        try:
            nquestions = int(squestions)
        except ValueError:
            print("An integer response is required.")
            squestions == None
    filename = input("What filename do you want to use to store your results so that you can review? ")
    return topic, nquestions, filename, level

# the quiz mechanism
def ask_questions(Q):
    # allows A B C D answers and X, skipping allowed.
    def get_letter_answer():
        ans = None
        while ans == None:
            ans = input('A B C D X ? ').upper()
            if ans == 'X':
                print('Question skipped')
            elif len(ans) > 1 or ans < 'A' or ans > 'D':
                ans = None
        return ans
    
    answersgiven = list()
    for ndx in range(len(Q)):       
        print(f"\nQ:{ndx+1}\t{Q.iloc[ndx]['Question']}")
        qtopic = list()
        for jdx in range(11): # this is the column index of the topics
            if Q.iloc[ndx,jdx]==1:
                qtopic.append(Q.columns[jdx])
        print(f"This question\'s topics: {', '.join(qtopic)}") 
        print(f"A -> {Q.iloc[ndx]['Choice A']}")
        print(f"B -> {Q.iloc[ndx]['Choice B']}")
        print(f"C -> {Q.iloc[ndx]['Choice C']}")
        print(f"D -> {Q.iloc[ndx]['Choice D']}")
        answersgiven.append(get_letter_answer())
    return answersgiven

# this interface provides the student with feedback on how to improve their knowledge using on the 'Response'
#     column of the database. A better, but much more involved way, is to supply a response for the
#     student's specific answer.
def result_summary(Q,A,filename):
    print("\n") # insert blanking lines to separate from quiz
    output = list() # where we store the output as we are both displaying and saving to a file
    output.append('*****Here are your quiz results!*****')
    for ndx in range(len(Q)): # loop through questions
        output.append(f"\nQ:{ndx+1}\t{Q.iloc[ndx]['Question']}") # the question itself
        output.append(f"FCC Q:\t{Q.iloc[ndx]['Question Identifier']}") # the FCC database identifier
        qtopic = list()
        # list all topics relevant to the question
        for jdx in range(11): # this is the column index of the topics
            if Q.iloc[ndx,jdx]==1: # could be 'True', but we chose 1
                qtopic.append(Q.columns[jdx])
        output.append(f"This question\'s topics: {', '.join(qtopic)}") 
        output.append(f"A -> {Q.iloc[ndx]['Choice A']}")
        output.append(f"B -> {Q.iloc[ndx]['Choice B']}")
        output.append(f"C -> {Q.iloc[ndx]['Choice C']}")
        output.append(f"D -> {Q.iloc[ndx]['Choice D']}")
        if Q.iloc[ndx]['Answer'] in A[ndx]: # identify whether the question was correctly answered
           output.append(f"Answer {A[ndx]} is correct!")
        else:
            output.append(f"chosen : {A[ndx]}, actual : {Q.iloc[ndx]['Answer']}")
            output.append(f"Study the following reference(s): {Q.iloc[ndx]['Response']}")
            # Response can encode interesting trivia too.  Use '\n' to encode line breaks in 
            #     the response string.
    print("\n".join(output))
    with open(filename+".txt",'w') as file:
        file.write("\n".join(output))

# maybe you like some of the functions above, but don't like the terminal user interface (TUI)?
if __name__ == "__main__":
    topic, nquestions, filename, level = start_screen() # Ask some questions of the user to set up the quiz
            # TODO ^ improve by creating a dictionary with user data
    quizdf = load_database(level) # ingest csv file (Excel export) and return a dataframe from Pandas
            # TODO ^ improve by adding image import into dataframe
    questions = choose_quiz_questions(quizdf,topic,nquestions) # take the user input and select quiz questions
    answersgiven = ask_questions(questions) # present the questions and collect responses
    result_summary(questions,answersgiven,filename) # study guide based on results
